package com.pi.shisan.component.impl;

import com.pi.shisan.component.BaseAbstractComponent;
import com.pi.shisan.component.util.ComponentThread;
import com.pi.shisan.util.spipoint.DataWriter;
import com.pi.shisan.util.spipoint.MergedSpi;
import com.pi.shisan.util.spipoint.MultipleFlushSpi;
import com.pi.shisan.util.spipoint.MultipleFlushSpiAsConsole;
import com.pi.shisan.util.spipoint.MultipleXyToSpiConverter;

import java.util.Random;

/**
 * 音乐电平组件
 */
public class MusicEffectComponent extends BaseAbstractComponent {

    /**
     * 渐变指标
     */
    private double topY = -1;

    /**
     * 擦除指标
     */
    private int lastTopY = -1;

    private int daily;

    private int value;

    public MusicEffectComponent(MultipleXyToSpiConverter spi, DataWriter dataWriter) {
        super(spi,dataWriter);
    }

    /**
     * 以1为分母的值
     * @param val
     */
    public void setVal(float val) {
        this.value = Math.round(val * (height / 8f));
        doRefresh(value);
    }

    @Override
    public void refresh() {
        doRefresh(value);
    }

    private void doRefresh(int val) {
        ComponentThread.execute(()->{
            _setVal(val);
        });
    }

    private void _setVal(int val) {
        final int startX = this.startX;
        final int width = this.width;
        int lowY = startY + height - 1; //height = 2, lowY = 1
        val = Math.min(val, height);
        int lastTopY = this.lastTopY;
        double thisTopY = this.topY;
        int topY = lowY - val + 1; // 1 - 2 + 1 = 0;
        if (thisTopY == -1) {
            thisTopY = topY;
            this.topY = thisTopY;
            daily = 100;
        }
        boolean needOpenMore;
        if (lastTopY == -1) {
            lastTopY = lowY;
            needOpenMore = true;
        } else {
            needOpenMore = lastTopY > topY;
        }
        for (int i = lastTopY; i < topY; i++) {
            if (i == Math.min(topY, thisTopY)) {
                continue;
            }
            for (int j = startX; j < width + startX; j++) {
                spi.delete(j, i);
            }
        }
        int daily = this.daily;
        this.lastTopY = topY;
        if (topY < thisTopY) {
            daily = 100;
            thisTopY = topY;
            this.topY = thisTopY;
            this.daily = daily;
        }
        if (needOpenMore) {
            for (int i = lastTopY; i >= topY; i--) {
                for (int j = startX; j < width + startX; j++) {
                    spi.put(j, i);
                }
            }
        }
        if (daily > 0) {
            daily --;
            this.daily = daily;
        } else if (thisTopY < lastTopY){
            for (int j = startX; j < startX + width; j++) {
                spi.delete(j, (int)thisTopY);
            }
            thisTopY +=0.1;
            this.topY = thisTopY;
            for (int j = startX; j < startX + width; j++) {
                spi.put(j, (int)thisTopY);
            }
        }
        flushData();
    }

    public static void main(String[] args) throws InterruptedException {

        MultipleFlushSpi multipleFlushSpi = new MultipleFlushSpiAsConsole(new MergedSpi(4,3));
        MusicEffectComponent component = new MusicEffectComponent(multipleFlushSpi,multipleFlushSpi);
        component.setH(24);
        component.setW(2);
        component.start();

        while (true) {
            int val = new Random().nextInt(25);
            component.setVal(val);
            System.out.println(val);
            Thread.sleep(2000);
        }

    }
}
